# -*- coding: utf-8 -*-
"""
--------------------------------------------
    Author:  niuqt
    Date:  8/9/2022 
--------------------------------------------
"""
from app01 import models
from django.core.paginator import Paginator
from django.http import JsonResponse

import pytz


from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.executors.pool import ThreadPoolExecutor
from apscheduler.triggers.interval import IntervalTrigger
from apscheduler.triggers.date import DateTrigger
from apscheduler.triggers.cron import CronTrigger

from apscheduler.schedulers.gevent import GeventScheduler

tz = pytz.timezone('Asia/Shanghai')
# # 定义以线程方式执行任务，最多20个线程同时执行
executors = {
    'default': ThreadPoolExecutor(20)  # 最多20个线程同时执行

}
schedulerall = BackgroundScheduler(timezone=tz, executors=executors)
schedulerall.start()





# 查询所有定时任务 log数据
def selectdsrw(request):
    nowPage = request.GET.get("page")
    limit = request.GET.get("limit")
    if limit == "":
        limit = 5

    alluser_list = models.DSRW.objects.values()
    paginator = Paginator(list(alluser_list), int(limit))
    # print(list(alluser_list))
    if int(nowPage) >= int(paginator.num_pages):
        nowPage = paginator.num_pages
    try:
        page = paginator.page(nowPage)
    except:
        page = paginator.page(paginator.num_pages)

    data = {'data': list(page), 'code': "200", 'count': paginator.count, 'page': page.number, 'limit': page.__len__(),
            'pages': paginator.num_pages

            }
    return JsonResponse(data)  # 返回所有的数据，和每页显示多好行，以及页数的设置


# 批量删除
def dsrw_log_delete_all(request):
    # 先判断发过来的是否是post请求
    if request.method == "POST":
        # 得到要删除的ids列表 值
        values = request.POST.getlist('ids')

        # 好像传过来的 values  是 ['3,5,7']  这样的形式，我们需要进一步的细化
        # print(values[0])
        # print(type(values[0]))
        # print(values[0].split(','))
        # print(type(values[0].split(',')))

        new_list = values[0].split(',')
        # print(new_list)

        for i in range(len(new_list)):
            # 如果id不为空，获取该字段，并将其删除，我们只删除book表，publisher表不变
            deleteID = int(new_list[i])
            book_obj = models.DSRW.objects.get(id=deleteID)
            book_obj.delete()
        # 删除成功返回显示页
        # return redirect('/curd/')
        data = {

            'code': "200",

        }
        return JsonResponse(data)


#####  定时任务结果

# 查询所有定时任务结果 数据
def selectdsrwresult(request):
    nowPage = request.GET.get("page")
    limit = request.GET.get("limit")
    if limit == "":
        limit = 5

    alluser_list = models.DSRWresult.objects.values()
    paginator = Paginator(list(alluser_list), int(limit))
    # print(list(alluser_list))
    if int(nowPage) >= int(paginator.num_pages):
        nowPage = paginator.num_pages
    try:
        page = paginator.page(nowPage)
    except:
        page = paginator.page(paginator.num_pages)

    data = {'data': list(page), 'code': "200", 'count': paginator.count, 'page': page.number, 'limit': page.__len__(),
            'pages': paginator.num_pages

            }
    return JsonResponse(data)  # 返回所有的数据，和每页显示多好行，以及页数的设置


# 批量删除
def dsrwresult_log_delete_all(request):
    # 先判断发过来的是否是post请求
    if request.method == "POST":
        # 得到要删除的ids列表 值
        values = request.POST.getlist('ids')
        new_list = values[0].split(',')

        for i in range(len(new_list)):
            # 如果id不为空，获取该字段，并将其删除，我们只删除book表，publisher表不变
            deleteID = int(new_list[i])
            book_obj = models.DSRWresult.objects.get(id=deleteID)
            book_obj.delete()
        # 删除成功返回显示页
        # return redirect('/curd/')
        data = {
            'code': "200",
        }
        return JsonResponse(data)


#  定时任务 计划

def selectdsrwswitch(request):
    nowPage = request.GET.get("page")
    limit = request.GET.get("limit")
    if limit == "":
        limit = 5

    alluser_list = models.DSRWswitch.objects.values()
    paginator = Paginator(list(alluser_list), int(limit))
    # print(list(alluser_list))
    if int(nowPage) >= int(paginator.num_pages):
        nowPage = paginator.num_pages
    try:
        page = paginator.page(nowPage)
    except:
        page = paginator.page(paginator.num_pages)

    data = {'data': list(page), 'code': "200", 'count': paginator.count, 'page': page.number, 'limit': page.__len__(),
            'pages': paginator.num_pages

            }
    return JsonResponse(data)  # 返回所有的数据，和每页显示多好行，以及页数的设置


# 修改 定时任务 计划
def editdsrwjh(request):
    if request.method == 'POST':

        dsrwid = request.POST.get("dsrwid", None)
        switch_name = request.POST.get("switch_name", None)
        switch_start_time = request.POST.get("switch_start_time", None)
        switch_end_time = request.POST.get("switch_end_time", None)
        id_active_id = request.POST.get("id_active_id", None)

        # id ,为表中的字段名，这个要注意
        if models.DSRWswitch.objects.filter(id=dsrwid).update(switch_name=switch_name,
                                                              switch_start_time=switch_start_time,
                                                              switch_end_time=switch_end_time,
                                                              id_active_id=id_active_id):
            return JsonResponse({"code": 200, "msg": "添加成功"}, safe=False)
        else:
            return JsonResponse({"code": 300, "msg": "添加失败"}, safe=False)


Holiday_time = {'Holiday_start_time': '', 'Holiday_end_time': ''}


#  通过传过来的id，进行对应的定时任务
def startdsrw(request):
    dsrw_id = request.GET.get("id", None)
    start_time = models.DSRWswitch.objects.filter(pk=dsrw_id).values('switch_start_time')[0]['switch_start_time']
    end_time = models.DSRWswitch.objects.filter(pk=dsrw_id).values('switch_end_time')[0]['switch_end_time']
    Holiday_time['Holiday_start_time'] = start_time
    Holiday_time['Holiday_end_time'] = end_time
    # print(start_time,end_time)
    StopAllRw()  # 不管执行哪个定时任务，都执行关闭所有之前的任务

    time.sleep(1)

    if dsrw_id == "1":
        dsrw_name_temp = models.DSRWpid.objects.filter(pk=1).values('dsrw_name')[0]['dsrw_name']
        if dsrw_name_temp != "上班模式":


            # 修改 id_active_id 的值 为 1，表示 在执行
            models.DSRWswitch.objects.filter(pk=1).update(id_active_id=1)
            models.DSRWswitch.objects.filter(pk=2).update(id_active_id=2)

            StartTimeNormal_py()

            return JsonResponse({"code": 200, "msg": "工作日模式定时任务开始执行"}, safe=False)
        else:
            return JsonResponse({"code": 200, "msg": "工作模式线程已经存在，请先点击放假模式、再次点击工作模式"}, safe=False)


    else:
        dsrw_name_temp = models.DSRWpid.objects.filter(pk=1).values('dsrw_name')[0]['dsrw_name']
        if dsrw_name_temp != "放假模式":

            models.DSRWswitch.objects.filter(pk=1).update(id_active_id=2)
            models.DSRWswitch.objects.filter(pk=2).update(id_active_id=1)

            StartTimeNormal_py()

            return JsonResponse({"code": 200, "msg": "放假模式定时任务开始执行"}, safe=False)
        else:
            return JsonResponse({"code": 200, "msg": "放假模式线程已经存在，请先点击工作模式、再次点击放假模式"}, safe=False)




#######################
import time
import paramiko
from apscheduler.schedulers.blocking import BlockingScheduler  # 定时 任务需要的包
import threading
import ctypes

## 设置全局 任务的PID
# qj_pid_num
## 设置全局 任务执行时刻 的 当时时间
# qj_time_running
## 设置全局 任务 id
# qj_rw_idname
## 设置全局  任务是否有执行
# qj_rw_isnot

# 全局 数据 字典
qj_date = {}






####   上班日 执行的命令
def StartTimeNormal_py():  # 利用多线程 解决 界面卡顿的问题
    # sched_Normal = BlockingScheduler(timezone='Asia/Shanghai')
    # sched_Holiday = BlockingScheduler(timezone='Asia/Shanghai')

    active_id_n = models.DSRWswitch.objects.filter(pk=1).values('id_active_id')[0]['id_active_id']
    # active_id_h = models.DSRWswitch.objects.filter(pk=2).values('id_active_id')[0]['id_active_id']

    if active_id_n == "1":
        schedulerall.add_job(UnLockXR, 'interval', seconds=60, id='上班模式')

        #print(schedulerall.get_jobs())
        # [<Job (id=dd模式 name=UnLockXR)>, <Job (id=上班模式 name=UnLockXR)>]

        #print(schedulerall.get_job('上班模式'))
        # UnLockXR (trigger: interval[0:01:00], next run at: 2022-09-22 11:48:49 CST)



        fj_panduan =  schedulerall.get_job('放假模式')
        if fj_panduan:
            # schedulerall.remove_job('放假模式')
            fj_panduan.remove()



        # sched_Normal.add_job(LockXR, 'interval',  seconds=60,  id='上班模式')
        # # 在 星期一 到 星期五 运行，每天的晚上22:00 unlock，每天的早上 8:00 lock
        # # 因为 星期六日，都要加入渲染的，所以在周六日晚上22点，在执行一次 unlock
        # sched_Normal.add_job(UnLockXR, 'cron', day_of_week='mon-sun', hour=8,
        #                      minute='52' )
        #
        # sched_Normal.add_job(LockXR, 'cron', day_of_week='mon-fri', hour=9,
        #                      minute='55')
        #
        # # 15分钟后 再次执行
        # sched_Normal.add_job(UnLockXR, 'cron', day_of_week='mon-sun', hour=21,
        #                      minute=17)
        #
        # sched_Normal.add_job(LockXR, 'cron', day_of_week='mon-fri', hour=8,
        #                      minute=17)
        #
        #
        # sched_Normal.start()  # 开始定时任务

        qj_date['qj_rw_idname'] = '上班模式'
        qj_date['qj_pid_num'] = '123456'
        pid_num(qj_date)


    # else:
    #     sched_Holiday.remove_all_jobs()


    # if active_id_h == "1":
    else:
        schedulerall.add_job(UnLockXR, 'interval', seconds=60, id='放假模式')
        sb_panduan = schedulerall.get_job('上班模式')
        if sb_panduan:
            schedulerall.remove_job('上班模式')

        # sched_Holiday.add_job(UnLockXR, 'interval', seconds=60, id='dd模式')
        # # 在 星期一 到 星期五 运行，每天的晚上22:00 unlock，每天的早上 8:00 lock
        # # 因为 星期六日，都要加入渲染的，所以在周六日晚上22点，在执行一次 unlock
        # sched_Holiday.add_job(UnLockXR, 'cron', day_of_week='mon-sun', hour=8,
        #                      minute='52', id='放假模式')
        #
        # sched_Holiday.add_job(LockXR, 'cron', day_of_week='mon-fri', hour=9,
        #                      minute='55')
        #
        # # 15分钟后 再次执行
        # sched_Holiday.add_job(UnLockXR, 'cron', day_of_week='mon-sun', hour=21,
        #                      minute=17)
        #
        # sched_Holiday.add_job(LockXR, 'cron', day_of_week='mon-fri', hour=8,
        #                      minute=17)
        #
        # sched_Holiday.start()  # 开始定时任务

        qj_date['qj_rw_idname'] = '放假模式'
        qj_date['qj_pid_num'] = '789456'
        pid_num(qj_date)

    # else:
    #     sched_Normal.remove_all_jobs()
    # sched_Normal.print_jobs()
    # sched_Normal.get_jobs()

# def StartTimeNormal_py():
#     Start_T_Normal = threading.Thread(target=__StartTimeNormal_py)
#     Start_T_Normal.start()
#     qj_pid_num = Start_T_Normal.ident
#     # print(Start_T_Normal.native_id)
#     qj_date['qj_pid_num'] = qj_pid_num  # 获取 任务的 pid
#     # 收集任务的pid
#
#     active_id_n = models.DSRWswitch.objects.filter(pk=1).values('id_active_id')[0]['id_active_id']
#     active_id_h = models.DSRWswitch.objects.filter(pk=2).values('id_active_id')[0]['id_active_id']
#
#     if active_id_n == "1":
#         qj_date['qj_rw_idname'] = '上班模式'
#     else:
#         qj_date['qj_rw_idname'] = '放假模式'
#     pid_num(qj_date)



import datetime


# 放假日执行
def __StartTimeHoliday_py():  # 利用多线程 解决 界面卡顿的问题

    # print(Holiday_time['Holiday_start_time'] )
    # print(Holiday_time['Holiday_end_time'] )
    sched_Holiday = BlockingScheduler(timezone='Asia/Shanghai')
    # sched_Holiday.add_job(UnLockXR, 'interval', seconds=10, id='放假日模式test')

    #  获得假期结束后的日期，因为这个不太好判断，所以在选择结束日期的时候 ，需要向后延期一天
    EndTime_y_value = int(Holiday_time['Holiday_end_time'].split('-')[0])  # 年
    EndTime_m_value = int(Holiday_time['Holiday_end_time'].split('-')[1])  # 月    注意输出的是 02  03  04 这种月份
    EndTime_d_value = int(Holiday_time['Holiday_end_time'].split('-')[2])  # 日

    # 获得定时任务 的 开始和结束时间  start_date="2021-08-30 17:48:20", end_date="2021-08-30 17:49:00"
    start_time_temp = str(Holiday_time['Holiday_start_time']) + " " + "20:59:00"
    end_time_temp = str(Holiday_time['Holiday_end_time']) + " " + "7:30:00"
    start_time_temp_t = str(Holiday_time['Holiday_start_time']) + " " + "22:16:00"

    # 放假期间，防止有人加班，去掉渲染，所以在假期内，每天的晚上22还需要 执行unlock
    # 设定周期开始时间start_date和结束时间end_date，及每24小时触发 一次 unlock
    # interval 模式是，在开始和结束时间内，循环间隔多少时间执行
    # hours 是固定的时间间隔
    sched_Holiday.add_job(UnLockXR, 'interval', start_date=start_time_temp, end_date=end_time_temp, hours=24,
                          id='放假模式')

    # 多次执行
    sched_Holiday.add_job(UnLockXR, 'interval', start_date=start_time_temp_t, end_date=end_time_temp, hours=24,
                          id='放假日模式2')

    # 放假 结束后的第一天 早上8点 lock
    # date  模式是在特定的时间，执行一次任务
    sched_Holiday.add_job(LockXR, 'date',
                          run_date=datetime.datetime(EndTime_y_value, EndTime_m_value, EndTime_d_value,
                                                     7, 59, 0), id='放假日模式3')

    sched_Holiday.add_job(LockXR, 'date',
                          run_date=datetime.datetime(EndTime_y_value, EndTime_m_value, EndTime_d_value,
                                                     8, 16, 0), id='放假日模式4')


    sched_Holiday.start()  # 开始定时任务


def StartTimeHoliday_py():
    Start_T_Holiday = threading.Thread(target=__StartTimeHoliday_py)
    Start_T_Holiday.start()
    qj_pid_num = Start_T_Holiday.ident
    qj_date['qj_pid_num'] = qj_pid_num  # 获取 任务的 pid
    # 收集任务的pid
    qj_date['qj_rw_idname'] = '放假模式'
    pid_num(qj_date)




# #  停止 之前 所有的定时任务
def StopAllRw():
    pid_num_temp = models.DSRWpid.objects.filter(pk=1).values('process_id')[0]['process_id']
    if len(str(pid_num_temp)) != 0:  # 通过字符串 的 len 是否为0，判断线程 是否存在，如果存在就强制kill
        tid_Start_T = ctypes.c_long(int(pid_num_temp))
        res_T = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid_Start_T, ctypes.py_object(SystemExit))
        if res_T == 1:
            # print("定时任务已经结束")
            pass
    ##  SystemExit   是一个 导致程序退出的一个python用法，如果在线程中使用，是可以导致线程退出的，但是如果在高IO的情况下，不要使用这个方法停止线程，试试看线程的标志方法


def succeed_info():
    #  定时任务函数 里边 设置 时间和是否 执行
    qj_time_running = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    qj_rw_isnot = "succeed"

    qj_date['qj_time_running'] = qj_time_running
    qj_date['qj_rw_isnot'] = qj_rw_isnot

    # print(qj_date)

    # 把每一次的定时任务  数据放在 指定的 数据库中
    models.DSRW.objects.create(queue_name=qj_date['qj_rw_idname'],
                               process_id=qj_date['qj_pid_num'], isnot_success=qj_date['qj_rw_isnot'],
                               publish_time_format=qj_date['qj_time_running'])

    # print(models.DSRWpid.objects.filter(pk=1).values('process_id')[0]['process_id'])


def pid_num(qj_date):
    # 定时任务的 pid  只保留一个
    # 还需要 保存 任务名称，便于 判断是否运行的为同一个定时任务，如果是同一个任务、那就在前端提示 任务已经运行、不在生成新的 线程
    restult_temp = models.DSRWpid.objects.filter(pk=1).exists()
    # print(restult_temp)

    if restult_temp:  # 如果 数据库中有pid 的数据，就更新，没有就新建一个 id = 1
        models.DSRWpid.objects.filter(pk=1).update(process_id=qj_date['qj_pid_num'], dsrw_name=qj_date['qj_rw_idname'])
    else:
        models.DSRWpid.objects.create(id="1", process_id=qj_date['qj_pid_num'],dsrw_name="name")


def result_info(Stdout_xx):
    #  定时任务函数 里边 设置 时间和是否 执行
    qj_time_running = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    qj_date['qj_time_running'] = qj_time_running

    qj_date['dsrw_result'] = Stdout_xx
    # print(qj_date)

    # 把每一次的定时任务  数据放在 指定的 数据库中
    models.DSRWresult.objects.create(queue_name=qj_date['qj_rw_idname'],
                                     process_id=qj_date['qj_pid_num'], dsrw_result=qj_date['dsrw_result'],
                                     publish_time_format=qj_date['qj_time_running'])


def fail_info():
    #  定时任务函数 里边 设置 时间和是否 执行
    qj_time_running = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    qj_rw_isnot = "fail"

    qj_date['qj_time_running'] = qj_time_running
    qj_date['qj_rw_isnot'] = qj_rw_isnot

    # print(qj_date)

    # 把每一次的定时任务  数据放在 指定的 数据库中
    models.DSRW.objects.create(queue_name=qj_date['qj_rw_idname'],
                               process_id=qj_date['qj_pid_num'], isnot_success=qj_date['qj_rw_isnot'],
                               publish_time_format=qj_date['qj_time_running'])


###############
def LockXR():
    pass


def UnLockXR():
    pass


# 查询不参加定时任务同事名单
def selectdnoxrname(request):
    nowPage = request.GET.get("page")
    limit = request.GET.get("limit")
    if limit == "":
        limit = 5

    alluser_list = models.DSRWnoxrname.objects.values()
    paginator = Paginator(list(alluser_list), int(limit))
    # print(list(alluser_list))
    if int(nowPage) >= int(paginator.num_pages):
        nowPage = paginator.num_pages
    try:
        page = paginator.page(nowPage)
    except:
        page = paginator.page(paginator.num_pages)

    data = {'data': list(page), 'code': "200", 'count': paginator.count, 'page': page.number, 'limit': page.__len__(),
            'pages': paginator.num_pages

            }
    return JsonResponse(data)  # 返回所有的数据，和每页显示多好行，以及页数的设置


# 修改 不参加 定时任务 同事名单
def editnoxrname(request):
    if request.method == 'POST':
        noxrid = request.POST.get("noxrid", None)
        colleague_name = request.POST.get("colleague_name", None)

        # id ,为表中的字段名，这个要注意
        if models.DSRWnoxrname.objects.filter(id=noxrid).update(colleague_name=colleague_name):
            return JsonResponse({"code": 200, "msg": "添加成功"}, safe=False)
        else:
            return JsonResponse({"code": 300, "msg": "添加失败"}, safe=False)


import pymysql


def XRList_hostname():
    pass


import datetime


# 获取没有用户的 机器
def List_hostname_no_owner():
    pass


#### 渲染日志机器 图标
# 一周前

def xrbtdata(request):
    if request.method == "POST":
        today = datetime.datetime.now().date()
        weekdelta = datetime.datetime.now().date() - datetime.timedelta(weeks=1)
        # print(weekdelta)

        res_set = models.xrtb.objects.filter(riqi__gte=weekdelta, riqi__lte=today).values()
        riqi_list = []
        xr_w_num_z01_list = []
        xr_w_num_z02_list = []
        no_x_num_z01_list = []
        no_x_num_z02_list = []
        no_o_num_z01_list = []
        no_o_num_z02_list = []
        xr_w_num_w01_list = []
        xr_w_num_w02_list = []
        no_x_num_w01_list = []
        no_x_num_w02_list = []
        no_o_num_w01_list = []
        no_o_num_w02_list = []
        for i in range(0,len(res_set)):
            # print(res_set[i])
            riqi_list.append(res_set[i]['riqi'])
            xr_w_num_z01_list.append(res_set[i]['xr_w_num_z01'])
            xr_w_num_z02_list.append(res_set[i]['xr_w_num_z02'])
            no_x_num_z01_list.append(res_set[i]['no_x_num_z01'])
            no_x_num_z02_list.append(res_set[i]['no_x_num_z02'])
            no_o_num_z01_list.append(res_set[i]['no_o_num_z01'])
            no_o_num_z02_list.append(res_set[i]['no_o_num_z02'])
            xr_w_num_w01_list.append(res_set[i]['xr_w_num_w01'])
            xr_w_num_w02_list.append(res_set[i]['xr_w_num_w02'])
            no_x_num_w01_list.append(res_set[i]['no_x_num_w01'])
            no_x_num_w02_list.append(res_set[i]['no_x_num_w02'])
            no_o_num_w01_list.append(res_set[i]['no_o_num_w01'])
            no_o_num_w02_list.append(res_set[i]['no_o_num_w02'])

        data = {
            'riqi_temp': riqi_list,
            'data_xr_w_num_z01': xr_w_num_z01_list,
            'data_xr_w_num_z02': xr_w_num_z02_list,
            'data_no_x_num_z01': no_x_num_z01_list,
            'data_no_x_num_z02': no_x_num_z02_list,
            'data_no_o_num_z01': no_o_num_z01_list,
            'data_no_o_num_z02': no_o_num_z02_list,
            'data_xr_w_num_w01': xr_w_num_w01_list,
            'data_xr_w_num_w02': xr_w_num_w02_list,
            'data_no_x_num_w01': no_x_num_w01_list,
            'data_no_x_num_w02': no_x_num_w02_list,
            'data_no_o_num_w01': no_o_num_w01_list,
            'data_no_o_num_w02': no_o_num_w02_list,

        }
        # print(data)
        return JsonResponse(data)
